package com.piece.admin.controller.system;

import com.piece.admin.model.TbSysDept;
import com.piece.admin.model.TbSysRole;
import com.piece.admin.service.TbSysDeptService;
import com.piece.admin.service.TbSysRoleService;
import com.piece.admin.support.TranslateEntity;
import com.piece.core.framework.annotation.permission.AclPermission;
import com.piece.core.framework.annotation.permission.SubmitPermission;
import com.piece.core.framework.constant.ExceptionConstants;
import com.piece.core.framework.enums.sql.SqlKey;
import com.piece.core.framework.support.bootstrap.DataTable;
import com.piece.core.framework.support.bootstrap.Order;
import com.piece.core.framework.support.bootstrap.QueryTable;
import com.piece.core.framework.support.bootstrap.TreeData;
import com.piece.core.framework.support.convert.Convert;
import com.piece.core.framework.support.response.AjaxResponse;
import com.piece.core.framework.util.object.ClassUtil;
import com.piece.core.framework.util.object.ObjectUtil;
import com.piece.core.framework.util.basic.I18nUtil;
import com.piece.core.framework.util.string.StringUtil;
import com.piece.core.log.client.dto.UserDTO;
import com.piece.core.log.config.UserContextHolder;
import com.piece.core.web.controller.FrameWorkController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.*;

@RestController
@Api(tags = {"部门管理"})
@RequestMapping("/api/system/dept")
public class SysDeptController extends FrameWorkController {

    @Autowired
    protected TranslateEntity translateEntity;

    @Resource
    private TbSysDeptService tbSysDeptService;

    @Resource
    private TbSysRoleService tbSysRoleService;

    @PostMapping("/list")
    @AclPermission(code = "system:dept:view")
    @ApiOperation(value = "查询部门列表")
    @ApiImplicitParam(value = "查询条件", dataTypeClass = QueryTable.class, type = "body")
    public List list() {
        QueryTable queryTable = initTable();
        List<Order> orders = new ArrayList<>();
        orders.add(new Order("orderNum", SqlKey.ASC));
        queryTable.setOrder(orders);
        DataTable dataTable = tbSysDeptService.findPage(queryTable);
        return dataTable.getData();
    }

    @PostMapping("/table")
    @AclPermission(code = "system:dept:view")
    @ApiOperation(value = "查询部门分页数据")
    @ApiImplicitParam(value = "查询条件", dataTypeClass = QueryTable.class, type = "body")
    public AjaxResponse table() {
        QueryTable queryTable = initTable();
        DataTable dataTable = tbSysDeptService.findPage(queryTable);
        return success(dataTable);
    }

    @PostMapping("/treeTable")
    @AclPermission(code = "system:dept:view")
    @ApiOperation(value = "查询部门分页树数据")
    @ApiImplicitParam(value = "查询条件", dataTypeClass = QueryTable.class, type = "body")
    public AjaxResponse treeTable() {
        QueryTable queryTable = initTable();
        Map<String, Object> params = queryTable.getParams();
        boolean findParent = false;
        queryTable.setParams(params);
        if (ObjectUtil.isEmpty(params.get("Q_deptName_S_LK"))) {
            params.put("Q_parentId_L_EQ", 0);
            findParent = true;
        }
        DataTable dataTable = tbSysDeptService.findPage(queryTable);
        List<TbSysDept> data = new ArrayList<>();
        List<TbSysDept> findDepts = dataTable.getData();
        List<TbSysDept> allDepts = null;
        if (findParent) {
            allDepts = tbSysDeptService.findAll();
        }
        for (Iterator<TbSysDept> iterator = findDepts.iterator(); iterator.hasNext(); ) {
            TbSysDept dept = iterator.next();
            if (findParent) {
                dept.setChildren(tbSysDeptService.findChildTable(allDepts, dept.getDeptId()));
            } else {
                dept = tbSysDeptService.findParentTable(dept);
            }
            data.add(dept);
        }

        dataTable.setData(data);
        return success(dataTable);
    }

    @GetMapping("/load")
    @AclPermission(code = "system:dept:view")
    @ApiOperation(value = "生成部门表单数据")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "部门ID"),
            @ApiImplicitParam(name = "pid", value = "部门父ID")
    })
    public AjaxResponse load() {
        long id = Convert.toLong(getRequest().getParameter("id"), 0L);
        long pid = Convert.toLong(getRequest().getParameter("pid"), 0L);
        TbSysDept dept = new TbSysDept(), p_dept = null;
        String parentName = "无";
        if (id != 0) {
            dept = tbSysDeptService.findById(id);
            pid = dept.getParentId();
            translateEntity.setEntityInfo(dept);
        } else if (pid != 0) {
            p_dept = tbSysDeptService.findById(pid);
            parentName = p_dept.getDeptName();
            dept.setParentId(pid);
            dept.setParentName(parentName);
        }
        return success(dept);
    }

    @SubmitPermission
    @PostMapping("/save")
    @AclPermission(code = "system:dept:add,system:dept:edit")
    @ApiOperation(value = "保存部门表单数据")
    @ApiImplicitParam(value = "部门表单数据", dataTypeClass = TbSysDept.class, type = "body")
    public AjaxResponse save() {
        TbSysDept dept;
        try {
            Long id = Convert.toLong(getRequest().getParameter("deptId"));
            if (ClassUtil.isEmpty(id)) {
                dept = new TbSysDept();
                setDefaultInfo(dept, true);
            } else {
                dept = tbSysDeptService.findById(id);
                setDefaultInfo(dept, false);
            }
            initDB(dept);
            tbSysDeptService.insertOrUpdate(dept);
            return success(I18nUtil.message(ExceptionConstants.SAVE_SUCCESS), null);
        } catch (Exception e) {
            return error(I18nUtil.message(ExceptionConstants.SAVE_FAILURE), e.getMessage());
        }
    }

    @SubmitPermission
    @PostMapping("/delete")
    @AclPermission(code = "system:dept:delete")
    @ApiOperation(value = "删除部门")
    @ApiImplicitParam(name = "ids", value = "部门ID集合")
    public AjaxResponse delete() {
        String ids = getRequest().getParameter("ids");
        if (StringUtil.isNotEmpty(ids)) {
            tbSysDeptService.delete(Convert.toLongArray(ids));
        }
        return success(I18nUtil.message(ExceptionConstants.DELETE_SUCCESS), null);
    }

    /**
     * 加载所有部门列表树
     */
    @PostMapping("/treeData")
    @AclPermission(code = "system:dept:view")
    @ApiOperation(value = "加载所有部门列表树")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "selected", value = "已选部门ID"),
            @ApiImplicitParam(name = "roleId", value = "角色ID"),
            @ApiImplicitParam(name = "from", value = "请求来源")
    })
    public List<TreeData> treeData() {
        String selected = getRequest().getParameter("selected");
        String roleId = getRequest().getParameter("roleId");
        // 请求来源
        String from = getRequest().getParameter("from");
        List<TreeData> result;
        if (StringUtil.isNotEmpty(roleId)) {
            TbSysRole role = tbSysRoleService.findById(Convert.toLong(roleId));
            result = tbSysDeptService.findTreeData(role);
        } else if (StringUtil.isNotEmpty(selected)) {
            List<TbSysDept> list = tbSysDeptService.findAll();
            result = tbSysDeptService.findTreeData(list, true, Convert.toStrList(selected));
        } else {
            result = tbSysDeptService.findTreeData();
        }
        if ("vue".equals(from)) {
            TreeData root = result.get(0);
            result = findChildTreeData(result, Convert.toStr(root.getId(), "0"));
            root.setChildren(result);
            List<TreeData> convertResult = new ArrayList<>();
            convertResult.add(root);
            return convertResult;
        }
        return result;
    }

    @GetMapping("/convertName")
    @ApiOperation(value = "根据部门ID加载部门名称")
    @ApiImplicitParam(name = "ids", value = "已选部门ID")
    public AjaxResponse convertName() {
        String ids = getRequest().getParameter("ids");
        if (StringUtil.isNotEmpty(ids)) {
            return success(tbSysDeptService.convertIdToNames(ids));
        }
        return success();
    }

    private void setDefaultInfo(TbSysDept dept, boolean insert) {
        UserDTO user = UserContextHolder.get();
        if (insert) {
            dept.setCreateBy(user.getId());
            dept.setCreateTime(new Date());
        }
        dept.setUpdateBy(user.getId());
        dept.setUpdateTime(new Date());
    }
}
